package com.sugon.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * 文件工具类
 *
 * @author YuXD
 * @since 2021-09-27
 */
@Slf4j
public class FileUtil {

    /**
     * 对图片或者PDF进行添加水印操作
     *
     * @param file
     * @param targetFile
     */
    public static void setWatermark(MultipartFile file, File targetFile) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
        String waterMarkName = ShiroUtils.getUserEntity().getNickName() + "上传于" + DateUtil.today();
        if ("pdf".equals(fileSuffix)) {
            // 对PDF添加水印
            try {
                setPdfWatermark(file.getInputStream(), targetFile, waterMarkName);
            } catch (DocumentException e) {
                log.error(e.getMessage(), e);
            }
        } else if (StrUtil.equalsAny(fileSuffix, "jpeg", "jpg")) {
            // 对图片添加水印
            setImageWatermark(file.getInputStream(), targetFile, waterMarkName);
        }
    }

    /**
     * 将pdf输入流中的pdf添加完水印后保存到targetFile 指定的位置
     *
     * @param input         原PDF输入刘
     * @param targetFile    输出文件的位置
     * @param waterMarkName 页脚添加水印
     * @throws DocumentException
     * @throws IOException
     */
    private static void setPdfWatermark(InputStream input, File targetFile, String waterMarkName) throws DocumentException, IOException {
        // 创建输出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetFile));
        // 创建PDF reader
        PdfReader reader = new PdfReader(input);
        PdfStamper stamper = new PdfStamper(reader, bos);

        // 获取总页数 +1, 下面从1开始遍历
        int total = reader.getNumberOfPages() + 1;
        // 使用classpath下面的字体库
        BaseFont base = null;
        try {
            base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
        } catch (Exception e) {
            // 日志处理
            log.error(e.getMessage(), e);
        }
        // 设置水印透明度
        PdfGState gs = new PdfGState();
        gs.setFillOpacity(0.4f);
        gs.setStrokeOpacity(0.4f);

        PdfContentByte content = null;
        for (int i = 1; i < total; i++) {
            // 在内容上方加水印
            content = stamper.getOverContent(i);
            // 在内容下方加水印
            // content = stamper.getUnderContent(i);
            content.saveState();
            content.setGState(gs);

            // 设置字体和字体大小
            content.beginText();
            content.setFontAndSize(base, 14);
            content.setColorFill(BaseColor.BLACK);
            // 设置字体样式
            float ta = 1F, tb = 0F, tc = 0F, td = 1F, tx = 0F, ty = 0F;
            // 设置加粗(加粗)
            ta += 0.25F;
            td += 0.05F;
            ty -= 0.2F;
            // 设置倾斜(倾斜程序自己改)
            tc += 0.2F;
            content.setTextMatrix(ta, tb, tc, td, tx, ty);
            // 设置相对于左下角位置(向右为x，向上为y)
            content.moveText(280F, 10F);
            // 显示text
            content.showText(waterMarkName);
            content.endText();
            content.stroke();
            content.restoreState();
        }
        // 关流
        stamper.close();
        reader.close();
    }

    /**
     * 图片添加水印
     *
     * @param input         图片输入流
     * @param targetFile    需要保存的目标路径
     * @param waterMarkName 水印内容
     */
    private static void setImageWatermark(InputStream input, File targetFile, String waterMarkName) {
        FileOutputStream outImgStream = null;
        try {
            // 读取原图片信息
            Image srcImg = ImageIO.read(input);
            int srcImgWidth = srcImg.getWidth(null);
            int srcImgHeight = srcImg.getHeight(null);
            // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            Font font = new Font("微软雅黑", Font.BOLD, 25);
            // 根据图片的背景设置水印颜色
            g.setColor(Color.RED);
            g.setFont(font);
            int x = srcImgWidth - getWatermarkLength(waterMarkName, g) - 10;
            int y = srcImgHeight - 10;
            g.drawString(waterMarkName, x, y);
            g.dispose();
            // 输出图片
            outImgStream = new FileOutputStream(targetFile);
            String targetFileName = targetFile.getName();
            ImageIO.write(bufImg, targetFileName.substring(targetFileName.lastIndexOf('.') + 1), outImgStream);
            outImgStream.flush();
            outImgStream.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (outImgStream != null) {
                try {
                    outImgStream.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
    }

    /**
     * 获取水印文字总长度
     *
     * @param waterMarkContent 水印的文字
     * @param g
     * @return 水印文字总长度
     */
    private static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }

}
